home *** CD-ROM | disk | FTP | other *** search
- //*****************************************************************************
- // C_Mnu.prg
- // Simple menu class for OBJECT v2.03
- // Copyright (c) 1991, JHK, JHK-Software, Piestany
- // Compile with: /N/M/W/A
- //-----------------------------------------------------------------------------
-
- #include "InKey.ch"
- #include "SetCurs.ch"
- #include "Object.ch"
-
- create class Mnu from Win
- export:
- var Help // {} //{Idx,...}
- var Items // {} //{"item1",...}
- var SelItems // {} //{lSelectable,...}
- var Cursor // (object of Cursor)
- var Choice // 1 //user selected
- var Top // 1 //top item in menu
- var CanAppend // false //append/delete command allowed
- var InsBlock // {|o|nil} //database insert_row_code_block
- var DelBlock // {|o|nil} //database delete_row_code_block
- method New=MnuNew //o:New()
- method Init=MnuInit //o:Init(Name,R,C,CurSize,Items,SelItems,Clr,Shadow)
- method Process=MnuProcess //o:Process(),;
- method Done=MnuDone //o:Done()
- endclass
-
-
- //*****************************************************************************
- // Mnu:New() --> self
- // initialize new object
- //
- constructor MnuNew()
- ::Help:= {}
- ::Items:= {}
- ::SelItems:= {}
- ::Cursor:= (object of Cursor)
- ::Choice:= 1
- ::Top:= 1
- ::CanAppend:= false
- ::InsBlock:= {|o|nil}
- ::DelBlock:= {|o|nil}
- return(self)
-
-
- //*****************************************************************************
- // Mnu:Init(Name,R,C,CurSize,Items,SelItems,Clr,Shadow) --> true
- // initialize new simple menu.
- //
- method function MnuInit(Name,R,C,CurSize,Items,SelItems,Clr,Shadow)
- local Rs,Cs
- local C2,aClr
- default Clr to m->Color:Menu
- Rs:=Min(Len(Items),MaxRow()-7)
- Cs:=Min(aWidth(Items,{|e|Len(e)-if(At("~",e)>0,1,0)}),MaxCol()-9)
- if Empty(SelItems)
- SelItems:=Array(Len(Items))
- AFill(SelItems,true)
- endif
- if Empty(::Help)
- ::Help:=Array(Len(Items))
- AFill(::Help,0)
- endif
- ::Cursor:Get()
- ::super(Win):GoodInit(Name,R,C,Rs,Cs,CurSize,Clr,Shadow)
- ::Items:=Items
- ::SelItems:=SelItems
- *
- R:=::Row+1
- C:=::Col+1
- C2:=::Col+::ColSize
- aClr:=ListAsArray(::Color)
- AAdd(aClr,if(m->tColor==1,GetBack(aClr[nNormal]),GetFore(aClr[nNormal]))+"/"+GetBack(aClr[nEnhanced]))
- DispBegin()
- ::super(Win):Paint(true,false)
- IEval(Rs,{|i|DrawItem(R++,C,C2,Cs,Items[i],SelItems[i],false,aClr)})
- if ::Choice>0
- R:=::Row+::Choice
- DrawItem(R,C,C2,Cs,Items[::Choice],SelItems[::Choice],true,aClr)
- endif
- DispEnd()
- return(true)
-
-
- //*****************************************************************************
- // Mnu:Process() --> nChoice
- // allow user select one from menu items.
- //
- method function MnuProcess()
- local R,C,Rs,Cs,R2,C2,Items,SelItems,aClr
- local OldRow,Row,Ch,i,Key,Msg
- SetCursor(SC_NONE)
- Msg:=SetDMsg()
- PreProcess(self,Msg,@R,@C,@Rs,@Cs,@R2,@C2,@Items,@SelItems,@aClr,@OldRow,@Row,@i)
- SaveHelpIdx({16})
- repeat
- TrueIdx(@Row,0,R,R2,SelItems)
- if OldRow<>Row
- DispBegin()
- DrawItem(OldRow,C,C2,Cs,Items[OldRow-R+1],SelItems[OldRow-R+1],false,aClr)
- DrawItem(Row,C,C2,Cs,Items[Row-R+1],SelItems[Row-R+1],true,aClr)
- DispEnd()
- endif
- OldRow:=Row
- i:=Row-R+1
- ReadHelpVar("MENU->"+NTrim(::Help[i]))
- Key:=PauseKey(0)
- ReadHelpVar("")
- if Key==K_ESC; i:=-Abs(i); endif
- if !SelItems[Abs(i)]; i:=-Abs(i); endif
- ::Choice:=i
- do case
- case Key==K_UP; TrueIdx(@Row,-1,R,R2,SelItems)
- case Key==K_DOWN; TrueIdx(@Row,+1,R,R2,SelItems)
- case Key==K_HOME; Row:=R
- case Key==K_END; Row:=R2
- case Key==K_INS; if ::CanAppend; Eval(::InsBlock, self); PreProcess(self,Msg,@R,@C,@Rs,@Cs,@R2,@C2,@Items,@SelItems,@aClr,@OldRow,@Row,@i); endif
- case Key==K_DEL; if ::CanAppend; Eval(::DelBlock, self); PreProcess(self,Msg,@R,@C,@Rs,@Cs,@R2,@C2,@Items,@SelItems,@aClr,@OldRow,@Row,@i); endif
- case Key==nSwapTask; Key:=K_ESC //exit from menu
- case Key==K_CTRL_RET; Key:=K_ENTER //select item
- case Key==K_ESC //dummy
- case Key==K_ENTER //dummy
- otherwise
- Ch:=Upper(Chr(Key))
- if ("0"<=Ch and Ch<="9") or ("A"<=Ch and Ch<="Z")
- Ch:="~"+Ch
- if (i:=AScan(Items,{|e| At(Ch,Upper(e))>0}))>0
- Row:=R+i-1
- StuffKey(K_ENTER)
- endif
- else
- Key:=K_ESC
- endif
- endcase
- until Key==K_ENTER or Key==K_ESC or Empty(Items)
- RestHelpIdx()
- if Key==K_ESC; ::Choice:=-Abs(::Choice); endif
- if Empty(Items); ::Choice:=0; SetLastKey(0); endif
- DOut(Msg)
- return(::Choice)
-
-
- //-----------------------------------------------------------------------------
- // Mnu::PreProcess(...) -->nil
- // (re)initialize local variables for Mnu:Process()
- //
- static function PreProcess(Mnu,Msg,R,C,Rs,Cs,R2,C2,Items,SelItems,aClr,OldRow,Row,i)
- DOut(Msg+if(Mnu:CanAppend,","+ResTxt(143),""))
- R:=Mnu:Row+1
- C:=Mnu:Col+1
- Rs:=Mnu:RowSize
- Cs:=Mnu:ColSize
- R2:=Mnu:Row+Mnu:RowSize
- C2:=Mnu:Col+Mnu:ColSize
- Items:=Mnu:Items
- SelItems:=Mnu:SelItems
- aClr:=ListAsArray(Mnu:Color)
- AAdd(aClr,if(m->tColor==1,GetBack(aClr[nNormal]),GetFore(aClr[nNormal]))+"/"+GetBack(aClr[nEnhanced]))
- i:=Mnu:Choice
- OldRow:=Row:=R+Abs(i)-1
- if i<0
- i:=-i
- DrawItem(Row,C,C2,Cs,Items[i],SelItems[i],true,aClr)
- endif
- return(nil)
-
-
- //-----------------------------------------------------------------------------
- // TrueIdx(@Idx,nDirection,R,R2,SelItems) --> true
- // evaluate true Idx for pop menu, check availability of the item
- //
- static function TrueIdx(Idx,nDirection,R,R2,SelItems)
- local i:=Len(SelItems)+1
- if AScan(SelItems,true)==0; return(true); endif
- if nDirection==0; Idx--; nDirection++; endif
- repeat
- i--
- Idx+=nDirection
- if Idx<R and Set(_SET_WRAP); Idx:=R2
- elseif Idx>R2 and Set(_SET_WRAP); Idx:=R
- elseif Idx<R; Idx:=R; if !SelItems[1]; nDirection:=+1; endif
- elseif Idx>R2; Idx:=R2; if !ATail(SelItems); nDirection:=-1; endif
- endif
- until SelItems[Idx-R+1] or i==0
- return(true)
-
-
- //-----------------------------------------------------------------------------
- // DrawItem(R,C,C2,S,It,SelIt,HiIt,Clr) --> true
- // draw one menu item for OChoice
- //
- static function DrawItem(R,C,C2,S,It,SelIt,HiIt,Clr)
- local cn,cl,i:=At("~",It)
- if m->tColor<>0
- cn:=Clr[if(SelIt,if(HiIt,nExtension,nNormal),nDisable)]
- cl:=Clr[if(SelIt,if(HiIt,nSelected,nLetter),nDisable)]
- else
- cn:=Clr[if(SelIt,if(HiIt,nSelected,nNormal),nDisable)]
- cl:=Clr[if(SelIt,nLetter,nDisable)]
- endif
- SetPos(R,C)
- if i>0
- DispOut(Left(It,i-1),cn)
- DispOut(SubStr(It,i+1,1),cl)
- DispOut(PadR(SubStr(It,i+2),C2-C-i+1),cn)
- else
- DispOut(PadR(It,C2-C+1),cn)
- endif
- return(true)
-
-
- //*****************************************************************************
- // Mnu:Done() --> true
- // destroy the simple menu.
- //
- method function MnuDone()
- ::Hide()
- ::Cursor:Set()
- return(true)
-
- //------------------------------------------------------- eof (c)JHK ----------
-
-